package factory.one.service;

import factory.one.entity.Deliver;
import factory.one.entity.Send;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.stereotype.Service;

import java.sql.*;
import java.util.List;
import java.util.Objects;

/**
 * @author sk.z
 * 2023/11/9
 **/
@Service
public class DeliverService {

    private final Logger logger = LoggerFactory.getLogger(DeliverService.class);
    private final JdbcTemplate jdbcTemplate;

    public DeliverService(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public Long add(Deliver deliver) {
        PreparedStatementCreator creator = con -> {
            PreparedStatement statement = con.prepareStatement(
                    "insert into DELIVER(order_id,sequence,number,create_user,create_time,status) values(?,?,?,?,?,?)",
                    Statement.RETURN_GENERATED_KEYS);
            statement.setLong(1, deliver.getOrderId());
            statement.setInt(2, deliver.getSequence());
            statement.setInt(3, deliver.getNumber());
            statement.setString(4, deliver.getCreateUser());
            statement.setTimestamp(5, new Timestamp(deliver.getCreateTime().getTime()));
            statement.setInt(6, deliver.getStatus());
            return statement;
        };
        GeneratedKeyHolder holder = new GeneratedKeyHolder();
        jdbcTemplate.update(creator, holder);
        return holder.getKey() == null ? null : holder.getKey().longValue();
    }

    public Deliver getById(Long deliverId) {
        return jdbcTemplate.queryForObject("select * from DELIVER where id = ?", new DeliverRowMapper(), deliverId);
    }

    public List<Deliver> listByOrder(Long orderId) {
        return jdbcTemplate.query("select * from DELIVER where order_id = ?", new DeliverRowMapper(), orderId);
    }

    public List<Deliver> listInSending(Long orderId) {
        return jdbcTemplate.query("select * from DELIVER where order_id = ? and status = 1", new DeliverRowMapper(), orderId);
    }

    public List<Deliver> listHaveSent(Long orderId) {
        return jdbcTemplate.query("select * from DELIVER where order_id = ? and status = 2", new DeliverRowMapper(), orderId);
    }

    public List<Deliver> listHistory(Long orderId) {
        return jdbcTemplate.query("select * from DELIVER where order_id = ? and status > 1", new DeliverRowMapper(), orderId);
    }

    //status = 1-新建(装载中) 2-已发货 3-取消发货
    public int updateStatus(Long id, int status) {
        return jdbcTemplate.update("update DELIVER set status = ? where id = ?", status, id);
    }

    public int setSequence(Long deliverId) {
        Deliver deliver = getById(deliverId);
        if (Objects.isNull(deliver) || deliver.getSequence() > 0) {
            return 0;
        }
        Integer nextSequence = getNextSequence(deliver.getOrderId());
        return jdbcTemplate.update("update DELIVER set sequence = ? where id = ?", nextSequence, deliverId);
    }

    public int setSequence(Long deliverId, Long orderId) {
        Integer nextSequence = getNextSequence(orderId);
        return jdbcTemplate.update("update DELIVER set sequence = ? where id = ?", nextSequence, deliverId);
    }

    private Integer getNextSequence(Long orderId) {
        List<Deliver> sendList = listByOrder(orderId);
        if (sendList == null || sendList.isEmpty()) {
            return 1;
        }
        int i = 0;
        for (Deliver s : sendList) {
            i = Math.max(i, s.getSequence());
        }
        return i + 1;
    }

    private static class DeliverRowMapper implements RowMapper<Deliver> {
        @Override
        public Deliver mapRow(ResultSet rs, int rowNum) throws SQLException {
            Deliver o = new Deliver();
            o.setId(rs.getLong("id"));
            o.setOrderId(rs.getLong("order_id"));
            o.setSequence(rs.getInt("sequence"));
            o.setNumber(rs.getInt("number"));
            o.setCreateUser(rs.getString("create_user"));
            o.setCreateTime(rs.getTimestamp("create_time"));
            o.setStatus(rs.getInt("status"));
            return o;
        }
    }

}
